// =============================================================
// CAction class
// ---------------------------------------
// Author : Woo-Hyun Kim
// Email : woorung@icu.ac.kr or woorung@nhncorp.com
// Date : Jul. 25, 2006
//----------------------------------------------------------------------
#include "CAction.h"
//----------------------------------------------------------------------
CAction::CAction(string &type, string &name)
{
	this->type = type;
	this->name = name;
	current_pos = 0;
}
//----------------------------------------------------------------------
CAction::~CAction()
{
}
//----------------------------------------------------------------------
int CAction::registerCommand(string &command)
{
	commands.push_back(CShellProcess(command));

	current_pos = commands.size();
	return current_pos;
}
//----------------------------------------------------------------------
int CAction::registerCommonTaskVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		common_task_variables[attr] = val;
		
		variable++;
	}
}
//----------------------------------------------------------------------
int CAction::registerTaskVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		task_variables[attr] = val;

		variable++;
	}
}
//----------------------------------------------------------------------
int CAction::registerActionVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		action_variables[attr] = val;

		variable++;                             
	}                                               
}
//----------------------------------------------------------------------
string &CAction::getName()
{
	return name;
}
//----------------------------------------------------------------------
string &CAction::getType()
{
	return type;
}
//----------------------------------------------------------------------
string &CAction::getParameter(char *cattr)
{
	string attr = cattr;
	return getParameter(attr);
}
//----------------------------------------------------------------------
string &CAction::getParameter(string &attr)
{
	string common_task_variable = common_task_variables[attr];
	string task_variable = task_variables[attr];
	string action_variable = action_variables[attr];

	if(action_variable!="") return action_variables[attr];
	else if(task_variable!="") return task_variables[attr];
	else return common_task_variables[attr];
}
//----------------------------------------------------------------------
int CAction::hasMoreCommands()
{
	return current_pos;
}
//----------------------------------------------------------------------
string &CAction::getNextCommand()
{
	int i = commands.size() - current_pos--;
	return commands[i].get();
}
//----------------------------------------------------------------------
void CAction::perform()
{
	if(type=="concurrent") { // concurrently
		vector<CShellProcess>::iterator current = commands.begin();
		while(current!=commands.end()) {
			current->start();
			current++;
		}

		// wait until commands are finished
		vector<CShellProcess>::iterator finished = commands.begin();
		while(finished!=commands.end()) {
			if(finished->waits()<0) {
				cout << finished->get_pid() << " was abnormally exited" << endl;
				exit(-1);
			}
			else {
				cout << "[execute] : " << finished->get() << endl;
				cout << endl;
				cout << "######################################################################" << endl;
				cout << " Depredicated function !!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
				cout << endl;
				cout << " the result will be printed out over stdout of the exeucting place" << endl;
				cout << "######################################################################" << endl;
/*
				cout << finished->getCommandResult() << endl;
				cout << endl;
*/
			}
			finished++;
		}
	}
	else if(type=="ordered") { // sequentially
		vector<CShellProcess>::iterator current = commands.begin();
		while(current!=commands.end()) {
			current->start();
			if(current->waits()<0) {
				cout << current->get_pid() << " was abnromally exited" << endl;
				exit(-1);
			}
			else {
				cout << "[execute] : " << current->get() << endl;
				cout << endl;
				cout << "######################################################################" << endl;
				cout << " Depredicated function !!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
				cout << endl;
				cout << " the result will be printed out over stdout of the exeucting place" << endl;
				cout << "######################################################################" << endl;
/*
				cout << current->getCommandResult() << endl;
				cout << endl;
*/
			}
			current++;
		}
	}
	else if(type=="local") {
		// invoke a local method
		//CMethod *method = (CMethod *) new CIndexMethods(name);
		CMethod *method = (CMethod *) new CCubeMethods(name);
		method->invoke(common_task_variables, task_variables, action_variables);
		delete method;
	}
	else if(type=="remote") {
		cout << "[execute] : " << name << endl;
		cout << "#### not yet implemented ###" << endl;
	}
}
//----------------------------------------------------------------------
